<template>
  <div class="tutorial-id-page w-1300">
    <div class="content">
      <div class="tutorial-chapter-headline">
        <div class="name" @click="backHomePage"><i class="ri-list-unordered"></i>{{ title }}</div>
        <Menu v-model="chapterUuid" :menu="menu" :tutorialId="tutorialId" />
      </div>
      <div class="tutorial-chapter-content">
        <div class="modal">
          <div class="tutorial-basic-info" v-if="!chapterUuid">
            <div class="top-description">
              <div class="logo">
                <img :src="headImg" alt="">
              </div>
              <div class="info">
                <div class="title">{{ title }}</div>
                <p class="ii"><em>作者：</em>{{ ownerName }}</p>
                <p class="ii"><em>简介：</em>{{ summary }}</p>
              </div>
            </div>
            <div class="anchor-point-list markdown-body">
              <div v-html="desc" v-if="desc"></div>
              <div class="important">注：以上所有数据内容均来自<a href="https://www.developers.pub/" target="_blank">开发者客栈</a></div>
            </div>
          </div>
          <nuxt-child @get-tocs="data => tocs = data" v-show="chapterUuid"></nuxt-child>
        </div>
      </div>
      <div style="position: sticky; top: 73px; width: 230px;">
        <div class="tocs-info-block" v-show="tocs.length">
          <div class="title"><p class="linear-border-bottom">目录</p></div>
          <ul class="toc-list gloab-scroll-bar">
            <li
              v-for="(item, index) in tocs"
              :key="index"
              class="toc-list-item"
              :class="{ active: item.active, h2: item.depth === 1, h3: item.depth > 1 }"
              :data-id="item.href"
            >
              <span
                @click.stop="scrollToPosition(item)"
                :title="item.name"
              >{{ item.name }}</span>
            </li>
          </ul>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import Menu from './components/Menu.vue'
import { md, getElementDistanceFromTop } from '~/util'
export default {
  name: 'TutorialUuidPage',
  layout: 'BaseLayout',
  components: { Menu },
  async asyncData ({ $axios, params }) {
    const { tutorialId, chapterUuid } = params
    const { data } = await $axios.post('/gimishare/api/v1/tutorial/detail', { tutorialId })
    const { treeRoot, summary, headImg, ownerName, desc } = data
    return {
      menu: treeRoot.children || [],
      title: treeRoot.title,
      summary,
      headImg,
      ownerName,
      desc: md.render(desc),
      tutorialId: Number(tutorialId),
      chapterUuid: Number(chapterUuid),
      tocs: [],
      scrollTimer: null,
      clickState: false
    }
  },

  head () {
    return {
      title: `${this.title} - 教程`,
      link: [
        {
          rel: 'stylesheet',
          href: '/md/markdown/juejin-markdown.min.css'
        },
        {
          rel: 'stylesheet',
          href: '/md/highlightjs/styles/atom-one-dark.min.css'
        },
        {
          rel: 'stylesheet',
          href: '/md/katex/katex.min.css'
        }
      ]
    }
  },

  methods: {
    scrollToPosition (navigatorItem) {
      this.clickState = true
      clearTimeout(this.scrollTimer)
      for (let i = 0; i < this.tocs.length; i++) {
        this.$set(this.tocs[i], 'active', navigatorItem.href === this.tocs[i].href)
      }
      const ele = document.querySelector(`.markdown-tutorial-show-content #${navigatorItem.href}`)
      const scrollTop = document.documentElement.scrollTop
      const offsetTop = getElementDistanceFromTop(ele)
      const maxScrollTop = document.querySelector('#__layout').clientHeight - document.documentElement.clientHeight
      const scrollPostion = Math.min(offsetTop - 80, maxScrollTop)
      this.scrollDocument(scrollPostion, scrollPostion < scrollTop ? 'up' : 'down')
    },

    /**
     * 滚动到指定位置
     * @param { position } string
     * @param { direction } string
     */
    scrollDocument (position, direction) {
      const scrollTop = document.documentElement.scrollTop
      if (direction === 'up') {
        const nextScrollTop = Math.max(position, scrollTop - (scrollTop - position) * 0.18)
        document.documentElement.scrollTop = nextScrollTop
        if (nextScrollTop > position) {
          this.scrollTimer = setTimeout(() => {
            this.scrollDocument(position, direction)
          }, 16)
        } else {
          this.clickState = false
        }
      } else {
        const nextScrollTop = Math.min(position, Math.ceil(scrollTop + (position - scrollTop) * 0.18))
        document.documentElement.scrollTop = nextScrollTop
        if (nextScrollTop < position) {
          this.scrollTimer = setTimeout(() => {
            this.scrollDocument(position, direction)
          }, 16)
        } else {
          this.clickState = false
        }
      }
    },

    backHomePage () {
      document.documentElement.scrollTop = 0
      this.$router.push(`/tutorial/${this.tutorialId}`)
    }
  },

  watch: {
    '$route.params.chapterUuid': {
      handler (v) {
        if (v) {
          this.chapterUuid = Number(v)
        } else {
          this.chapterUuid = null
        }
      },
      immediate: true
    }
  }
}
</script>
<style lang="less" scoped>
.tutorial-id-page {
  margin-top: 12px;
  .content {
    margin-top: 12px;
    display: flex;
    align-items: flex-start;
    .tutorial-chapter-headline {
      width: 260px;
      position: fixed;
      top: 73px;
      bottom: 12px;
      background-color: #fff;
      border-radius: 4px;
      padding: 12px 0;
      display: flex;
      flex-direction: column;
      .name {
        font-size: 14px;
        padding: 0 18px;
        margin-bottom: 12px;
        font-weight: 600;
        color: #000;
        border-bottom: 1px solid #f1f1f190;
        padding-bottom: 12px;
        cursor: pointer;
        // display: flex;
        // align-items: center;
        i {
          margin-right: 6px;
          font-size: 16px;
          position: relative;
          top: 1px;
        }
      }
    }
    .tutorial-chapter-content {
      margin: 0 12px;
      padding-left: 260px;
      flex: 1;
      width: 0;
      .modal {
        background-color: #fff;
        min-height: 100vh;
        border-radius: 4px;
        padding: 18px 24px;
        .tutorial-basic-info {
          .top-description {
            display: flex;
            align-items: center;
            border-bottom: 1px solid #f1f1f1;
            padding-bottom: 24px;
            margin-bottom: 24px;
            .logo {
              width: 150px;
              font-size: 0;
              font-size: 0;
              border-radius: 4px;
              overflow: hidden;
              border: 1px dashed #f1f1f1;
              padding: 8px;
              img {
                width: 100%;
                border-radius: 4px;
              }
            }
            .info {
              padding-left: 12px;
              .title {
                font-size: 24px;
                font-weight: 600;
                color: #000;
              }
              .ii {
                color: #000;
                padding: 8px 0;
                em {
                  color: #999;
                  font-style: normal;
                }
              }
            }
          }
          .anchor-point-list {
            .important {
              color: #ff0000;
              a {
                margin-left: 6px;
              }
            }
          }
        }
      }
    }
    .tocs-info-block {
      background: #fff;
      border-radius: 4px;
      padding: 10px 4px 10px 0;
      .title {
        padding: 0 20px;
        line-height: 36px;
        color: #000;
      }
      .toc-list {
        list-style: none;
        margin: 0;
        max-height: 360px;
        margin-top: 10px;
        padding: 0;
        position: sticky;
        &-item {
          line-height: 32px;
          padding: 0 20px 0 10px;
          position: relative;
          font-size: 13px;
          span {
            color: #000;
            padding: 0 12px;
            border-radius: 4px;
            display: block;
            overflow: hidden;
            white-space: nowrap;
            text-overflow: ellipsis;
            cursor: pointer;
            &:hover {
              color: var(--primary-color) !important;
            }
          }
          &.active {
            &:before {
              content: "";
              position: absolute;
              top: 50%;
              left: 4px;
              width: 6px;
              height: 6px;
              transform: rotate(45deg);
              margin-top: -3px;
              background: var(--primary-color);
            }
            span {
              color: var(--primary-color) !important;
            }
          }
          &.h2, &.h3 {
            font-size: 12px;
            line-height: 28px;
          }
          &.h2 {
            span {
              color: #4c4c4c;
            }
          }
          &.h3 {
            span {
              color: #999;
            }
          }
        }
      }
    }
  }
}
</style>
